package com.lvy.hczn.front.business.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lvy.hczn.front.business.common.CacheConstants;
import com.lvy.hczn.front.business.dto.Param;
import com.lvy.hczn.front.business.mapper.OutboundOrderDetailMapper;
import com.lvy.hczn.front.business.service.OutboundOrderDetailService;
import com.lvy.hczn.front.business.service.WarehousingEntryService;
import com.lvy.hczn.front.common.core.redis.RedisCache;
import com.lvy.hczn.front.common.exception.UtilException;
import com.lvy.hczn.front.system.domain.business.*;
import com.lvy.hczn.front.business.mapper.OutboundOrderMapper;
import com.lvy.hczn.front.business.service.OutboundOrderService;
import com.lvy.hczn.front.system.service.SpuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class OutboundOrderServiceImpl extends ServiceImpl<OutboundOrderMapper, OutboundOrder> implements OutboundOrderService {

    @Autowired
    private OutboundOrderMapper outboundOrderMapper;

    @Autowired
    private OutboundOrderDetailService outboundOrderDetailService;

    @Autowired
    private SpuService spuService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private WarehousingEntryService warehousingEntryService;

    /**
     * 根据出库单查询出库单及详情
     *
     * @param outboundOrder
     * @return
     * @author yw
     * @date 2023-08-20 15:33:10
     */
    @Override
    public OutboundOrder selectIncludeDetailByOutboundOrderCode(OutboundOrder outboundOrder) {
        if (StrUtil.isEmpty(outboundOrder.getOutboundOrderCode())) {
            throw new UtilException("出库单编号为空");
        }
        OutboundOrder model = outboundOrderMapper.selectOne(Wrappers.<OutboundOrder>lambdaQuery().eq(OutboundOrder::getOutboundOrderCode, outboundOrder.getOutboundOrderCode()));
        if (model != null) {
            List<OutboundOrderDetail> orderDetailList = outboundOrderDetailService.list(Wrappers.<OutboundOrderDetail>lambdaQuery().eq(OutboundOrderDetail::getOutboundOrderCode, model.getOutboundOrderCode()));
            model.setList(orderDetailList);
        }
        return model;
    }

    /**
     * 从数据转发中心获取仓库运输出库但
     *
     * @param outboundOrder
     * @return
     * @author yw
     * @date 2023-08-27 19:46:56
     */
    @Override
    public void syncOutboundOrderFromTransmit(OutboundOrder outboundOrder) {
        super.saveOrUpdate(outboundOrder);
        if (outboundOrder.getList() != null && !outboundOrder.getList().isEmpty()) {
            outboundOrder.getList().forEach(outboundOrderDetail -> {
                Spu spu = spuService.getOne(Wrappers.<Spu>lambdaQuery().eq(Spu::getSpuCode, outboundOrderDetail.getGoodsCode()).last("limit 1"));
                if (spu != null) {
                    outboundOrderDetail.setSpuId(spu.getId());
                    outboundOrderDetailService.saveOrUpdate(outboundOrderDetail);
                } else {
                    log.error("syncOutboundOrderFromTransmitError：{}", outboundOrderDetail.getGoodsCode());
                }
            });
        }
    }

    /**
     * 仓库出库完成
     *
     * @param param
     * @return
     * @author yw
     * @date 2023-08-28 11:35:27
     */
    @Override
    public void clearOutboundCodeByClient(Param param) {
        if (StrUtil.isEmpty(param.getDeliveryOrderCode())) {
            throw new UtilException("出库单为空");
        }
        //todo clientId 校验
        String key = CacheConstants.REDIS_KEY_SOCKET_CLIENT + ":" + param.getUpOrDownPolicy().getClientId() + ":outboundCode";
        redisCache.del(key);

        ThreadUtil.execAsync(() -> {
            OutboundOrder outboundOrder = super.getOne(Wrappers.<OutboundOrder>lambdaQuery().eq(OutboundOrder::getOutboundOrderCode, param.getDeliveryOrderCode()));
            /**出库完成，提交出库单到平台**/
            if (outboundOrder != null) {
                List<OutboundOrderDetail> orderDetailList = outboundOrderDetailService.list(Wrappers.<OutboundOrderDetail>lambdaQuery().eq(OutboundOrderDetail::getOutboundOrderCode, param.getDeliveryOrderCode()));
                List<String> detailList = orderDetailList.stream().filter(item -> !StrUtil.isEmpty(item.getDataType())).map(OutboundOrderDetail::getDataType).collect(Collectors.toList());
                if (!orderDetailList.isEmpty()) {
                    WarehousingEntry warehousingEntry = new WarehousingEntry();
                    warehousingEntry.setEntryCode(outboundOrder.getOutboundOrderCode());
                    warehousingEntry.setServiceCode(outboundOrder.getServiceCode());
                    warehousingEntry.setDataTypeList(detailList);
                    warehousingEntryService.commitToPlatform(warehousingEntry, false, true);
                }
            }
        });
    }
}
